﻿using System.Collections.Generic;
using System.Text;

namespace DanMuHelper.Tools
{
    /// <summary>
    /// 文本工具类
    /// </summary>
    public static class StringExtension
    {
        private static readonly StringBuilder reusableStringBuilder = new StringBuilder();

        public static string Literal(this string s)
        {
            return $"\"{s.ToSourceCode()}\"";
        }

        public static string ToSourceCode(this string s)
        {
            if (s == null) return "null";
            var len = s.Length;
            if (len == 0) return string.Empty;
            // quote special characters
            for (var pos = 0; pos < len; pos++)
            {
                var ch = s[pos];
                switch (ch)
                {
                    case '\n':
                        reusableStringBuilder.Append("\\n");
                        break;
                    case '\r':
                        reusableStringBuilder.Append("\\r");
                        break;
                    case '\t':
                        reusableStringBuilder.Append("\\t");
                        break;
                    case '\"':
                        reusableStringBuilder.Append("\\\"");
                        break;
                    default:
                        reusableStringBuilder.Append(ch);
                        break;
                }
            }
            var result = reusableStringBuilder.ToString();
            reusableStringBuilder.Clear();
            return result;
        }

        /// <summary>
        /// 截取尾部字符串
        /// </summary>
        public static string Tail(this string s, int n)
        {
            if (string.IsNullOrEmpty((s)))
                return string.Empty;
            var len = s.Length;
            // get the last n characters
            return s.Substring(n >= len ? 0 : len - n, n);
        }

        public static string Shorten(this string s, int maxLength, string ellipsis = " [...]")
        {
            if (string.IsNullOrEmpty(s))
                return string.Empty;
            if (s.Length <= maxLength)
                return s;
            return s.Substring(0, maxLength - ellipsis.Length) + ellipsis;
        }

        public static List<string> Shorten(this List<string> data, int maxLines, string ellipsis = "[...]")
        {
            if (data == null || data.Count <= maxLines)
                return data;
            var result = new List<string>();
            for (var i = 0; i < maxLines; i++)
            {
                result.Add(data[i]);
            }
            result.Add(ellipsis ?? "[...]");
            return result;
        }

        public static string[] Shorten(this string[] data, int maxLines, string ellipsis = "[...]")
        {
            if (data == null || data.Length <= maxLines)
                return data;
            var result = new List<string>();
            for (var i = 0; i < maxLines; i++)
            {
                result.Add(data[i]);
            }
            result.Add(ellipsis ?? "[...]");
            return result.ToArray();
        }

        public enum OverflowMode
        {
            /// <summary>
            /// 直接截断
            /// </summary>
            Truncate,
            /// <summary>
            /// 超过部分显示省略号
            /// </summary>
            Ellipsis,
        }

        /// <summary>
        /// 字符串显示优化, 超过长度会被截断或显示省略号 (ASCII字符长度为1, 其他字符长度为2), 注意这个只是逻辑层的限制, 显示效果还需要借助Text组件的Overflow属性
        /// </summary>
        /// <param name="s"></param>
        /// <param name="overflowMode"></param>
        /// <param name="maxWidth"></param>
        /// <returns></returns>
        public static string OptimizeText(this string s, OverflowMode overflowMode, int maxWidth)
        {
            if (string.IsNullOrEmpty(s))
                return string.Empty;
            if (maxWidth > 0)
            {
                // TODO: 为达到最佳效果, 可以考虑使用TextGenerator来计算宽度
                // TODO: 全角转半角
                // 英文字符宽度为1, 中文字符宽度为2
                var width = 0;
                var nChars = s.Length;
                for (var pos = 0; pos < nChars; pos++)
                {
                    var ch = s[pos];
                    if (ch >= 0x4E00 && ch <= 0x9FBB)
                    {
                        // 中文字符
                        width += 2;
                    }
                    else
                    {
                        width++;
                    }
                    if (width >= maxWidth)
                    {
                        if (overflowMode == OverflowMode.Ellipsis)
                        {
                            return s.Substring(0, pos + 1) + "...";
                        }
                        else
                        {
                            return s.Substring(0, pos + 1);
                        }
                    }
                }
            }
            return s;
        }
    }
}
